package com.lianyu507.tools;

import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.util.AttributeFactory;

import java.io.IOException;
import java.io.StringReader;
import java.util.*;
import java.util.regex.Pattern;

/**
 * Created by Peter on 16/6/16.
 */
public class PhraseProcess {

    private Queue<PhraseTerm> phraseTermQueue;

    private  Map<String,Integer> resultData;//Integer是关键字出现的位置
    private static final Map<String,String> ignoredMap=new HashMap<>();

    static{
        ignoredMap.put("are","");
        ignoredMap.put("and","");
        ignoredMap.put("can","");
        ignoredMap.put("could","");
        ignoredMap.put("for","");
        ignoredMap.put("about","");
        ignoredMap.put("with","");
        ignoredMap.put("the","");
        ignoredMap.put("will","");

    }

    private AutoPhraseTokenizer tokenizer;
    public PhraseProcess(){

    }

    private void init(){
        resultData=new TreeMap<>();
        phraseTermQueue=new LinkedList<PhraseTerm>();
        AttributeFactory factory = AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY;
        this.tokenizer= new AutoPhraseTokenizer(factory,this);
        tokenizer.addAttribute(CharTermAttribute.class);
    }

    public Map<String, Integer> getResultData() {
        return resultData;
    }

    public void addTerm(String content,int start,int end){
        PhraseTerm phraseTerm=new PhraseTerm();
        phraseTerm.setContent(content);
        phraseTerm.setStart(start);
        phraseTerm.setEnd(end);
        phraseTermQueue.add(phraseTerm);
    }



    public void process(String englishStr){
        try {
        this.init();
        this.tokenizer.setReader(new StringReader(englishStr));
        this.tokenizer.reset();
//        CharTermAttribute term =tokenizer.addAttribute(CharTermAttribute.class);
        while (tokenizer.incrementToken()){
        }
        } catch (IOException e) {
            e.printStackTrace();
        }


        while (phraseTermQueue.size()>0){
            PhraseTerm term=phraseTermQueue.poll();
            String current=term.getContent();
            if(term.upperCase){
                current=checkNext(current,term);
            }
            if(!isIgnore(current)){
                resultData.put(current,term.start);
            }
        }
//        for(String key:resultData.keySet()){
//            System.out.println(key);
//        }
    }


    /**
     * 1. 把大写的名字合并一个短语
     * 2. 把长度小于3的删除
     * 3. 去掉重复的
     */
    private boolean isIgnore(String checkStr){
        if(checkStr.length()<3){
            return true;
        }
        if(resultData.containsKey(checkStr)){
           return true;
        }
        if(ignoredMap.containsKey(checkStr.toLowerCase())){
            return true;
        }
        if(Pattern.matches("(.*)(\\d+)(.*)", checkStr)){
            return true;
        }

        return false;
    }
    public String checkNext(String current,PhraseTerm term){
        PhraseTerm next=phraseTermQueue.peek();
        if(next==null){
            return current;
        }
        if(next.upperCase && next.start-term.end<2){
            current=current+" "+next.getContent();
            phraseTermQueue.poll();
            return checkNext(current,next);
        }else{
            return current;
        }
    }


    public class PhraseTerm{

        private String content;
        private int start;
        private int end;
        private boolean upperCase;

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
            if(content!=null && content.charAt(0)<97){
                upperCase=true;
            }
        }

        public int getStart() {
            return start;
        }

        public void setStart(int start) {
            this.start = start;
        }

        public int getEnd() {
            return end;
        }

        public void setEnd(int end) {
            this.end = end;
        }

        public boolean isUpperCase() {
            return upperCase;
        }

        public void setUpperCase(boolean upperCase) {
            this.upperCase = upperCase;
        }
    }
}
